# -*- coding: utf-8 -*-

"""
Module implementing MainWindow.
"""
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QMessageBox, QTableWidget
from PyQt5.QtCore import QStringListModel
from PyQt5.QtWidgets import QApplication, QWidget, QListView, QLabel, QHBoxLayout, QAbstractItemView

from PyQt5.QtGui import QIntValidator
from PyQt5.QtCore import QTimer
from ui_tool import *
from time import sleep
from PyQt5.QtWidgets import QFileDialog
from PyQt5 import Qt

import json
# 正则表达式，用于打印分割文本
import re
from socket import *
import time #导入time模块

import struct
import datetime
import configparser

import io
import os
import sys

import json
from collections import defaultdict
# 多线程
from threading import Thread
################################################################################################################################################################################

# 主函数
baseDir = "" # 搜索的根目录
notSearchFolderArr = [ 'vx_attachments', 'vx_recycle_bin' ] # 不搜索的目录
#searchFileTypeArr = ['.json'] # 搜索的文件类型
searchFileName = [ 'vx.json' ]


# 搜索一个文件目录 传入一个文件目录路径
def searchFolder(folderPath):
	folderName = os.path.split(folderPath)[-1]
	searFilePathArr = []
	if os.path.exists(folderPath) and (folderName not in notSearchFolderArr): # 判断路径是有效文件夹
		fileArr = os.listdir(folderPath) # 获取文件夹下的所有内容(文件和文件夹)
		for item in fileArr:
			currentPath = folderPath+'\\'+item
			(fileName,fileType)	= os.path.splitext(item)
			fileType = fileType.lower()
			#print(fileName)
			#print(fileName + fileType)
			if os.path.isfile(currentPath) and (fileName + fileType in searchFileName):	# 处理文件
			#if os.path.isfile(currentPath) and (fileType in searchFileTypeArr):	# 处理文件
				searFilePathArr.append(currentPath)
				#print(currentPath)

			if os.path.isdir(currentPath) and (item not in notSearchFolderArr): # 处理文件夹
				innerFileArr = searchFolder(currentPath) # 递归搜索
				searFilePathArr.extend(innerFileArr)

	return searFilePathArr



tmp_tag_list_cache = list()
split_mark = '::'
all_tag_dict = defaultdict(set)


# 读取文件到json
def file_to_json(filename):
	try:
		data = None
		with open (filename, encoding="UTF-8") as f:
			data = f.read()
			#print(data)
		return data #.decode('UTF-8')
	except Exception as e:
		return r''

# 把json文件处理为行数据
def json_to_list_datas(json_str) :
	header_dic = json.loads(json_str)

	files = header_dic['files']
	#print(files)
	for file_info in files:
		filename = file_info['name']
		tags = file_info['tags']
		#print()
		for tag in tags:
			#print(tag + ' <--:' + filename)
			tmp_tag_list_cache.append(tag + split_mark + filename)
			#all_tag_dict[tag] = 

# 从行数据构造为字典，key为tag，value为set
# https://www.cnpython.com/qa/689087
def line_datas_to_dict() :
	for line in tmp_tag_list_cache:
		c1, c2 = line.split(split_mark)
		all_tag_dict[c1].add(c2)
		#print(all_tag_dict)
	#print(all_tag_dict)

# 查询字典里面的set（用于后续）
def dump_dict():
	# 遍历字典
	for key in all_tag_dict:
		#print(item.key())
		#print(item)
		#print(item[0] + "--" + item[1])
		for file in all_tag_dict[key]:
			print(key + ' <--:' + file)
			pass
# 判断文件是否有某个标签
def is_file_in_tag(filename, tag):
	if filename in all_tag_dict[tag]:
		return True
	return False

def get_file_in_all_sets() :
	result_set = set()
	for key in all_tag_dict:
		#print(item.key())
		#print(item)
		#print(item[0] + "--" + item[1])
		result_set = result_set | all_tag_dict[key]
	return result_set

# 查看文件所属的标签
def list_file_in_which_set(filename) :
	# 遍历字典
	result = set()
	for key in all_tag_dict:
		#print(item.key())
		#print(item)
		#print(item[0] + "--" + item[1])
		if is_file_in_tag(filename, key) :
			result.add(key)
	return result

# 获取标签对应的文件集合
def get_tag_set(tagname):
	return all_tag_dict[tagname]

# 在当前集合，探索出可以搜索的tag
# 场景： 点击了一个标签，然后得到一个新的列表，在这个列表下求出其他标签
# 思路：点击标签以后，得到标签下的所有文件，根据这些文件，反算出文件所在的标签
def print_file_tag_which_in_set(set_):
	result_tag_set = set()
	for file in set_:
		result_tag_set |= list_file_in_which_set(file)

	#print(result_tag_set)
	return result_tag_set

class MainWindow(QMainWindow, Ui_MainWindow):
	def closeEvent(self, event):
		#print("Quit without question")
		sys.exit(0)
		#reply = QMessageBox.question(self, '提示',
		#				"确认退出吗",
		#				QMessageBox.Yes | QMessageBox.No,
		#				QMessageBox.No)
		#if reply == QMessageBox.Yes:
		#	pass
		#else:
		#	event.ignore()
	def ui_all_tags_list_update(self):
		# 遍历字典
		#item_list = list()
		for key in all_tag_dict:
			#print(item.key())
			#item_list.append(key)
			self.add_item_to_listview(self.listview_all_tags_list, key)
			#self.model_all_tags_list.insertRows(self.model_current_tags.rowCount(), 1)
			#data = key
			#index = self.model_all_tags_list.index(self.model_all_tags_list.rowCount()-1)
			#self.model_current_tags.setData(index, data)
		#self.model_all_tags_list.setStringList(item_list)
		#self.all_tags_list = item_list
		#self.listview_all_tags_list.setModel(self.model_all_tags_list)
		#
		#self.model_all_tags_list = QStringListModel(self)                # 1
		#self.model_all_tags_list.setStringList(item_list)           # 2
		#self.listview_all_tags_list.setModel(self.model_all_tags_list)   # 3


	# 清空
	def clr_istview(self, listview):
		# 所有标签
		if listview == self.listview_all_tags_list:
			self.all_tags_list.clear()
			self.model_all_tags_list.setStringList(self.all_tags_list)
		# 建议标签
		elif listview == self.listview_suggest_tag :
			self.suggest_tag_list.clear()
			self.model_suggest_tag_list.setStringList(self.suggest_tag_list)
		# 当前标签
		elif listview == self.listview_cur_selected :
			self.current_tags_list.clear()
			self.model_current_tags.setStringList(self.current_tags_list)
		# 搜索结果
		elif listview == self.listview_search_result_list :
			self.search_result_list.clear()
			self.model_search_result.setStringList(self.search_result_list)
		else :
			pass



	# 从listview 删除一个成员，并返回此成员
	def del_item_from_listview(self, listview, item_index):
		item = ""
		# 所有标签
		if listview == self.listview_all_tags_list:
			item = self.all_tags_list[item_index]
			self.all_tags_list.pop(item_index)
			self.model_all_tags_list.setStringList(self.all_tags_list)
		# 建议标签
		elif listview == self.listview_suggest_tag :
			item = self.suggest_tag_list[item_index]
			self.suggest_tag_list.pop(item_index)
			self.model_suggest_tag_list.setStringList(self.suggest_tag_list)
		# 当前标签
		elif listview == self.listview_cur_selected :
			item = self.current_tags_list[item_index]
			self.current_tags_list.pop(item_index)
			self.model_current_tags.setStringList(self.current_tags_list)
		# 搜索结果
		elif listview == self.listview_search_result_list :
			item = self.search_result_list[item_index]
			self.search_result_list.pop(item_index)
			self.model_search_result.setStringList(self.search_result_list)
		else :
			pass
		print("Del item :[ " + item +" ] ")
		return item

	def add_item_to_listview(self, listview, item):
		# 所有标签
		if listview == self.listview_all_tags_list:
			if item not in self.all_tags_list:
				self.all_tags_list.append(item)
			#self.model_all_tags_list = QStringListModel(self)
			self.model_all_tags_list.setStringList(self.all_tags_list)
			self.listview_all_tags_list.setModel(self.model_all_tags_list)
		# 建议标签
		elif listview == self.listview_suggest_tag :
			if item not in self.suggest_tag_list:
				self.suggest_tag_list.append(item)
			#self.model_suggest_tag_list = QStringListModel(self)
			self.model_suggest_tag_list.setStringList(self.suggest_tag_list)
			self.listview_suggest_tag.setModel(self.model_suggest_tag_list)
		# 当前标签
		elif listview == self.listview_cur_selected :
			if item not in self.current_tags_list:
				self.current_tags_list.append(item)
			#self.model_current_tags = QStringListModel(self)
			self.model_current_tags.setStringList(self.current_tags_list)
			self.listview_cur_selected.setModel(self.model_current_tags)
		# 搜索结果
		elif listview == self.listview_search_result_list :
			if item not in self.search_result_list:
				self.search_result_list.append(item)
			#self.model_search_result = QStringListModel(self)
			self.model_search_result.setStringList(self.search_result_list)
			self.listview_search_result_list.setModel(self.model_search_result)
		else :
			pass
		
	def ui_search_result_list_update(self):
		# 遍历字典
		item_list = list()
		for tag in self.model_current_tags.stringList():
			#print(tag)
			item_list.append(tag)
			#self.model_all_tags_list.insertRows(self.model_current_tags.rowCount(), 1)
			#data = key
			#index = self.model_all_tags_list.index(self.model_all_tags_list.rowCount()-1)
			#self.model_current_tags.setData(index, data)
		#self.model_all_tags_list.setStringList(item_list)
		#self.listview_search_result_list.setModel(self.model_all_tags_list)

		# BUG 空集和其他集合的交集是空集
		result_set = set()
		# 遍历整个字典
		for key in all_tag_dict:
			# 判断当前的key是否在 选择的ui列表中
			if key in item_list:
				if result_set : # 空集和其他集合的交集是空集，因此需要先判断
					result_set = result_set & all_tag_dict[key]
				else:
					result_set =  all_tag_dict[key]
		item_list = list()
		for key in result_set:
			#print(item.key())
			item_list.append(key)
		#print(item_list)
		self.model_search_result.setStringList(item_list)
		self.listview_search_result_list.setModel(self.model_search_result)

		# 根据搜索结果，得到新的标签池（用于进一步筛选 ）
		result = set()
		for file in item_list:
			print("Checking is file [" + file + "] have more tag" )
			for key in all_tag_dict:
				if is_file_in_tag(file, key) :
					result.add(key)
					print("Add tag: " + key)
		print("All item list")
		print(self.model_current_tags.stringList())
		for tag in result:
			#print(tag)
			if not tag in self.model_current_tags.stringList():
				print(tag)
				self.add_item_to_listview(self.listview_suggest_tag, tag)
                
		#print(result)

	@pyqtSlot()
	def on_pushButton_brower_clicked(self) :
		fname = QFileDialog.getExistingDirectory(self,'open file', '/')
		if fname:
			self.edit_vnote_path.setText(fname)

	@pyqtSlot()
	def on_pushButton_reflash_clicked(self) :
		try:
			fname = self.edit_vnote_path.text()
			if not fname:
				return
			allResArr = searchFolder(fname)
			#print("Done")
			tmp_tag_list_cache = list()
			for vx_json in allResArr:
				#print(vx_json)
				vx_json = vx_json.replace('\\','/')
				json_str = file_to_json(vx_json)
				#print(json_str)
				if len(json_str) == 0 :
					continue
				json_to_list_datas(json_str)
				#break
			#print('\n'.join(allResArr))
			line_datas_to_dict()
			all_set = get_file_in_all_sets()
			self.ui_all_tags_list_update()

			#print_file_tag_which_in_set(all_set)
			#dump_dict()
		except Exception as e:
			print("Exception: %s" % str(e))
			sys.exit(1)

	@pyqtSlot()
	def move_suggest_tag_to_curlist(self) :
		index = self.listview_suggest_tag.currentIndex().row()
		item = self.del_item_from_listview(self.listview_suggest_tag, index)
		self.add_item_to_listview(self.listview_cur_selected, item)

		#if listview == self.listview_all_tags_list:
		#	self.model_current_tags.insertRows(self.model_current_tags.rowCount(), 1)
		#
		#	data = self.listview_all_tags_list.currentIndex().data()
		#	index = self.model_current_tags.index(self.model_current_tags.rowCount()-1)
		#	self.model_current_tags.setData(index, data)
		#	self.model_all_tags_list.removeRows(self.listview_all_tags_list.currentIndex().row(), 1)
		#else:
		#	self.model_all_tags_list.insertRows(self.model_all_tags_list.rowCount(), 1)
		#
		#	data = self.listview_cur_selected.currentIndex().data()
		#	index = self.model_all_tags_list.index(self.model_all_tags_list.rowCount()-1)
		#	self.model_all_tags_list.setData(index, data)
		#	self.model_current_tags.removeRows(self.listview_cur_selected.currentIndex().row(), 1)
		self.ui_search_result_list_update()
		return
	def __init__(self, parent=None):

		super(MainWindow, self).__init__(parent)
		self.setupUi(self)
		#self.tableWidget.setColumnCount(1)
		self.suggest_tag_list = list()

		# 如何使用listview管理数据
        #    self.list = ['123']                      创建list
		#    self.model = QStringListModel()          创建model
		#    self.listView = ...					  创建listview
        #    self.model.setStringList(self.list)      为model配置list
        #    self.listView.setModel(self.model)       为listview配置model

		# 所有标签
		self.all_tags_list = list() #['item %s' % i for i in range(11)]	 # 1
		self.model_all_tags_list = QStringListModel(self)                # 1
		self.model_all_tags_list.setStringList(self.all_tags_list)       # 2
		self.listview_all_tags_list.setModel(self.model_all_tags_list)   # 3

		self.listview_all_tags_list.doubleClicked.connect(lambda: self.select_swap_tag(self.listview_all_tags_list))		
		self.listview_all_tags_list.setEditTriggers(QAbstractItemView.NoEditTriggers)


		# 建议的标签
		self.suggest_tag_list = list()
		self.model_suggest_tag_list = QStringListModel(self) 
		self.model_suggest_tag_list.setStringList(self.suggest_tag_list)
		self.listview_suggest_tag.setModel(self.model_suggest_tag_list)

		self.listview_suggest_tag.doubleClicked.connect(self.move_suggest_tag_to_curlist)
		self.listview_suggest_tag.setEditTriggers(QAbstractItemView.NoEditTriggers)


		# 当前标签
		self.current_tags_list = list()
		self.model_current_tags = QStringListModel(self)
		self.model_current_tags.setStringList(self.current_tags_list)
		self.listview_cur_selected.setModel(self.model_current_tags)

		self.listview_cur_selected.doubleClicked.connect(lambda: self.select_swap_tag(self.listview_cur_selected))
		self.listview_cur_selected.setEditTriggers(QAbstractItemView.NoEditTriggers)


		# 搜索结果
		self.search_result_list = list()
		self.model_search_result = QStringListModel(self)
		self.model_search_result.setStringList(self.search_result_list)
		self.listview_cur_selected.setModel(self.model_search_result)
		self.model_search_result = QStringListModel(self)

	def test_func(self, listview):
		print(111)
		pass

	# 实现列表项目在不同的列表中跑来跑去
	def select_swap_tag(self, listview):
		self.clr_istview(self.listview_suggest_tag)
		# 交换选择
		item = ""
		index = 0
		if listview == self.listview_cur_selected:	
			index = self.listview_cur_selected.currentIndex().row()
			item = self.del_item_from_listview(listview, index)

			self.add_item_to_listview(self.listview_all_tags_list, item)

		if listview == self.listview_all_tags_list:	
			index = self.listview_all_tags_list.currentIndex().row()
			item = self.del_item_from_listview(listview, index)

			self.add_item_to_listview(self.listview_cur_selected, item)
		
		self.ui_search_result_list_update()
		return
		# list1的内容跑到list2那边去
		if listview == self.listview_all_tags_list:							 # 6
			self.model_current_tags.insertRows(self.model_current_tags.rowCount(), 1)

			data = self.listview_all_tags_list.currentIndex().data()
			index = self.model_current_tags.index(self.model_current_tags.rowCount()-1)
			self.model_current_tags.setData(index, data)
			self.model_all_tags_list.removeRows(self.listview_all_tags_list.currentIndex().row(), 1)
		else:
			self.model_all_tags_list.insertRows(self.model_all_tags_list.rowCount(), 1)

			data = self.listview_cur_selected.currentIndex().data()
			index = self.model_all_tags_list.index(self.model_all_tags_list.rowCount()-1)
			self.model_all_tags_list.setData(index, data)
			self.model_current_tags.removeRows(self.listview_cur_selected.currentIndex().row(), 1)
		self.ui_search_result_list_update()
		return
		# 保持list1不变，而list2删除
		if listview == self.listview_all_tags_list:							 # 6
			self.model_current_tags.insertRows(self.model_current_tags.rowCount(), 1)

			data = self.listview_all_tags_list.currentIndex().data()
			index = self.model_current_tags.index(self.model_current_tags.rowCount()-1)
			self.model_current_tags.setData(index, data)
		else:													   # 7
			self.model_current_tags.removeRows(self.listview_cur_selected.currentIndex().row(), 1)



if __name__ == "__main__":
	import sys
	app = QtWidgets.QApplication(sys.argv)

	ui = MainWindow()
	ui.show()

	sys.exit(app.exec_())

